from selenium import webdriver
from lxml import etree
import requests
import tkinter as tk
import time
import threading
from PIL import Image,ImageTk
import cv2
import imageio
import imutils
import os
import pygame
from moviepy.editor import VideoFileClip,AudioFileClip,afx

#cv2只读取英文路径,路径不能带有中文，否则读取出来的为空值类型
#先将所有的图片转化为大小相同，这里定义为（300,300)
#这里路径为GUI下载图片的路径
#获取文件夹下面图片的名字信息
#全局变量
global name
name='./static/生成的图片视频.mp4'
global name1
name1='./static/合成视频.mp4'

#将图片合成视频
def chu_image():
    global path_name
    #获取图片保存的路径
    path_name=save.get()
    all_folds = os.listdir(path_name)
    all_image = [x for x in all_folds if '.' in x]
    
    #对图片进行处理
    for i in range(len(all_image)):
        base_url=path_name
        filename=base_url+'\image{}.jpg'.format(i+1)
        filename1=base_url+'1\image{}.jpg'.format(i+1)
        #读取图片
        try:
           if os.path.exists(filename)==False:
               continue
           else:
               img=Image.open(filename)
              #对图片进行裁剪
               #裁剪并将RGBA模式的转化WieRGB模式
               img_resize=img.resize((300,300),Image.NEAREST).convert('RGB')
               #为了保证原文件不被替换，将调整尺寸大小后的图片保存到一个新的文件夹里面
               img_resize.save(filename1)
        except :
            #将异常文件进行删除
            print("未知异常")
            os.remove(filename)
            continue
    
    #转化图片为视频
    all_folds1 = os.listdir(path_name+'1')
    #获取文件夹下面图片的名字信息
    all_image1 = [x for x in all_folds1 if '.' in x]
    #进行视频转化
    img1 = cv2.imread(path_name+'1\image1.jpg')
    imgInfo = img1.shape
    size = (imgInfo[1],imgInfo[0])
    #print(size)
    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    #定义视频名称
    videoWrite = cv2.VideoWriter(name,fourcc,1,size)# 写入对象
    for k in range(len(all_image1)):
        fileName =path_name+'1\image{}.jpg'.format(k+1) 
        imgr = cv2.imread(fileName)
        videoWrite.write(imgr)# 写入方法 1 jpg data
    videoWrite.release()
    #读取生成的视频文件
def add_audio():
    #为生成的视频添加背景音乐
    result_video=VideoFileClip(name) 
    #读取背景音乐
    audio_clip=AudioFileClip('./static/what am I.mp3')
    #设置背景音乐循环,时间与视频一样长
    audio=afx.audio_loop(audio_clip,duration=result_video.duration)
    result=result_video.set_audio(audio)
    #保存视频
    result.write_videofile(name1,fps=24)
    #获取和视频一样长的视频
    video1 = VideoFileClip(name1) 
    audio2 = video1.audio#获取他的音频 
    audio2.write_audiofile('./static/why.mp3')

#爬取部分
def main():
    #从搜索框中获取搜索名字
    word = key.get()
    #无界面模式
    options = webdriver.ChromeOptions()
#     无界面启动，也可以直接设置options.headless=True
    options.add_argument('headless')
    driver = webdriver.Chrome(options=options)
    driver.implicitly_wait(10)#设置隐式等待
    url='https://image.baidu.com/search/index?tn=baiduimage&word='+word
    driver.get(url)
    driver.enconding='UTF-8'
    # 获取页面初始高度
    js = "return action=document.body.scrollHeight"
    height = driver.execute_script(js)
    # 将滚动条调整至页面底部
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
    time.sleep(3)	
    #定义初始时间戳（秒）
    t1 = int(time.time())
    # 重试次数
    #定义循环标识，用于终止while循环
    status = True
    	# 重试次数
    num=0
    while status:
    	# 获取当前时间戳（秒）
        t2 = int(time.time())
    	# 判断时间初始时间戳和当前时间戳相差是否大于30秒，小于30秒则下拉滚动条
        if t2-t1 <30:
            new_height = driver.execute_script(js)
            if new_height > height :
                time.sleep(2)
                driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
    			# 重置初始页面高度
                height = new_height
    			# 重置初始时间戳，重新计时
                t1 = int(time.time())
        elif num < 3:                        # 当超过30秒页面高度仍然没有更新时，进入重试逻辑，重试3次，每次等待30秒
            time.sleep(3)
            num = num+1
        else:    # 超时并超过重试次数，程序结束跳出循环，并认为页面已经加载完毕！
            print("滚动条已经处于页面最下方！")
            status = False
    		# 滚动条调整至页面顶部
            driver.execute_script('window.scrollTo(0, 0)')
            break
        content = driver.page_source.encode('utf-8')
        #解析网页数据
        source=etree.HTML(content)
    
        #获取图片链接
        pic_img=source.xpath('//div[@class="imgbox-border"]/a/img/@data-imgurl')
        
        header={'User-Agent':'Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43'}
        for i in range(len(pic_img)):
            pic = requests.get(pic_img[i],headers=header) 
        	#获取图片保存的路径
            path=save.get()
            base_url=path +"\image{}.jpg".format((i+1))
            with open(base_url,'wb') as f:
               f.write(pic.content)
    t1 = "爬虫结束！开始合成视频"
    text1.insert(tk.INSERT, t1)
     #图片下载完成就开始合成视频吧
    time.sleep(2)
    chu_image()
    time.sleep(1)
    add_audio()

#清除事件
def cannel():
    text.delete('1.0','end')
    print('delete!')

# 键盘绑定事件。回车即搜索，esc则清空文本
def click(event):
    if event.keysym=="Return":
        main()
def cannel_esc(event):
    if event.keysym=="Escape":
        cannel()

root=tk.Tk()
root.title('welcome to image_xiazai system')
root.bg='black'
width,height=root.maxsize()
root.geometry("{}x{}".format(width, height))
tk.Frame(root,bg='black')

#分框架进行设计
#fm1
#内容标题
fm1=tk.Frame(bg='black')
titlelabel=tk.Label(fm1,text='百度图片下载和展示',font=('微雅软黑',50),fg='white',bg='black')
titlelabel.pack()
fm1.pack(side=tk.TOP,expand=tk.YES,fill='x',pady=20)
#
#fm2
fm2=tk.Frame(bg='black')
fm2_left=tk.Frame(fm2,bg='black')
fm2_right=tk.Frame(fm2,bg='black')
fm2_left_top=tk.Frame(fm2_left,bg='black')
fm2_left_bottom=tk.Frame(fm2_left,bg='black')
#
##设置输入的关键词
key=tk.StringVar(root,value='')
text=tk.Entry(fm2_left_top,font=('微软雅黑',15),width='20',fg='#22C9C9',textvariable=key)
preButton=tk.Button(fm2_left_top,text='搜索名字',bg='pink',fg='white',font=('微软雅黑',15),width='16',command=main)
preButton.pack(side=tk.LEFT)
text.pack(side=tk.LEFT,fill='y',padx=16)
fm2_left_top.pack(side=tk.TOP,fill='x')
#
##设置图片保存位置
save=tk.StringVar(root,value='')
tEntry=tk.Entry(fm2_left_bottom,font=('微软雅黑',15),width='20',fg='#22C9C9',textvariable=save)
tButton=tk.Button(fm2_left_bottom,text='保存路径',bg='#22C9C9',fg='white',font=('微软雅黑',15),width='16')
tButton.pack(side=tk.LEFT)
tEntry.pack(side=tk.LEFT,fill='y',padx=20)
fm2_left_bottom.pack(side=tk.TOP,pady=10,fill='x')
fm2_left.pack(side=tk.LEFT,padx=60,pady=20,expand=tk.YES,fill='x')


#设置显示框
text1=tk.Entry(fm2_right,font=('微软雅黑',15),width='20',fg='#22C9C9')
text1Button=tk.Button(fm2_right,text='下载完成显示',bg='#22C9C9',fg='white',font=('微软雅黑',15),width='16')
text1Button.pack(side=tk.RIGHT)
text1.pack(side=tk.RIGHT,fill='y',padx=20)

#global path_name
#path_name=save.get()
#设置播放视频的按钮
nextVideoImg= ImageTk.PhotoImage(file ='./static/baidu1.jpg',width=100, height=200) 
#设置播放视频
def play_next_video():
    text.delete(0,tk.END)
    tEntry.delete(0,tk.END)
    #加载视频的路径,name为设置生成视频的名字
    video_path=name
    #使用imagio模块读取视频，
      #可以选择解码工具
    video=imageio.get_reader(video_path,'ffmpeg')
#    视频流提取视频帧
    for videoFrame in video:
        videoFrame=imutils.resize(videoFrame,width=400,height=400)
        #更改颜色空间
        image=cv2.cvtColor(videoFrame,cv2.COLOR_BGR2RGB)
        image=Image.fromarray(image)
        image=ImageTk.PhotoImage(image)
        #配置
        panel.configure(image=image)
        panel.image=image
        time.sleep(2)
#定义音频文件

def play_audio():
    #初始化混音器模块
    pygame.mixer.init()
    #加载音频，
    track=pygame.mixer.music.load('./static/why.mp3')
    pygame.mixer.music.play()

#定义开始播放
def start_play_video():
        #采用多线程加载视频
       thread=threading.Thread(target=play_next_video,args=())
       thread.start()
       t2=threading.Thread(target=play_audio,args=())
       t2.start()

#绑定事件
nextVideoButton=tk.Button(fm2_right,image=nextVideoImg,width=100, height=80,text='视频展示',bg='black',command=start_play_video)
nextVideoButton.pack(expand=tk.YES)
fm2_right.pack(side=tk.RIGHT,padx=60,pady=20,expand=tk.YES,fill='x')
fm2.pack(side=tk.TOP,expand=tk.YES,fill="x")

# fm3
fm3=tk.Frame(bg='black')
#在fm3上放一张图片
load = Image.open('./static/color.jpg') 
initIamge= ImageTk.PhotoImage(load)  
panel = tk.Label(fm3,image=initIamge,width=800,height=800)  
panel.image = initIamge  
panel.pack()
fm3.pack(side=tk.TOP,expand=tk.YES,fill='both',pady=10)
root.mainloop()







